package com.auto.api.core.type.marge;

import com.auto.api.annotation.BeanMarge;
import com.auto.api.core.entity.BeanMargeContext;
import com.auto.api.core.type.AbstractParseBeanHandler;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.beanutils.PropertyUtils;

/**
 * @program:
 * @description: BeanMarge类型转换抽象类
 * @author: liangshf
 * @create: 2020-09-24
 */
public abstract class AbstractBeanMargeHandler extends
    AbstractParseBeanHandler<BeanMargeContext, Object> implements BeanMargeTypeHandler {

    @Override
    public Boolean beforeParse(BeanMargeContext parseTypeContext) {
        try {
            //过滤合并对象中不存在的属性
            Set<String> fieldSet = Arrays.asList(PropertyUtils.getPropertyDescriptors(parseTypeContext.getResult())).stream().map(
                PropertyDescriptor:: getName).collect(Collectors.toSet());
            parseTypeContext.setProps(parseTypeContext.getProps().stream().filter(i -> fieldSet.contains(i.getName())).collect(
                Collectors.toList()));

            Annotation annotation = parseTypeContext.getClazz().getAnnotation(BeanMarge.class);
            if (annotation != null && annotation instanceof BeanMarge) {
                parseTypeContext.setHasBeanMarge(true);
                BeanMarge beanMarge = (BeanMarge) annotation;
                String margeKey = beanMarge.margeKey();
                Set<String> margeFieldSet = parseTypeContext.getProps().stream().map(PropertyDescriptor:: getName).collect(Collectors.toSet());
                //合并的结果集不包含margeKey
                if (!margeFieldSet.contains(margeKey)) {
                    logger.info("bean {}合并的结果集不包含margeKey {}", parseTypeContext.getSimpleClassName(), margeKey);
                    return true;
                }
                parseTypeContext.setMargeKey(margeKey);
                Object resultValue = PropertyUtils.getSimpleProperty(parseTypeContext.getResult(), margeKey);
                Object margeValue = PropertyUtils.getSimpleProperty(parseTypeContext.getMargeObj(), margeKey);
                if (resultValue.equals(margeValue)) {
                    parseTypeContext.setDataMarge(true);
                }
            } else {
                parseTypeContext.setHasBeanMarge(false);
            }
        } catch (Exception e) {
            logger.info("数据聚合初始化参数错误：{}" ,e.getMessage());
            parseTypeContext.setHasBeanMarge(false);
            throw new RuntimeException(e);
        }
        return true;
    }
}
